#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import os
import subprocess
import threading
import time
import pickle
import logging
import platform
import shutil
import tempfile
import uuid
import io
import sys
import queue
import concurrent.futures

# 在Python 3.4中，typing模块不是标准库的一部分
# 尝试导入typing，如果不可用则定义类型别名
try:
    from typing import List, Dict, Any, Union, Tuple, Optional, Callable
except ImportError:
    # 为了向后兼容Python 3.4，定义空类型别名
    class _DummyType:
        def __getitem__(self, item):
            return None
    
    List = Dict = Union = Tuple = _DummyType()
    Any = Optional = object
    
    # 定义Callable作为函数
    def Callable(*args, **kwargs):
        return None

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(filename)s - %(lineno)d - %(message)s',
    handlers=[logging.StreamHandler()]
)

class Network:
    """
    提供用于多个IP之间通信的静态方法的类，
    包括消息发送、文件传输和命令执行功能。
    每个实例既可以作为服务端也可以作为客户端。
    """
    
    DEFAULT_PORT = 9999
    BUFFER_SIZE = 4096
    ENCODING = 'utf-8'
    TIMEOUT = 30  # 秒
    
    # 消息队列，用于存储接收到的消息
    _message_queue = queue.Queue()
    
    # 线程池，用于异步操作
    _thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10)
    
    # 监听状态标志
    _listening = True
    _server_running = False
    _server_thread = None
    
    @staticmethod
    def start_server(port=DEFAULT_PORT, callback=None):
        """
        启动一个监听传入连接的服务器。
        
        参数:
            port: 监听的端口
            callback: 当接收到命令时执行的可选回调函数
            
        返回:
            启动的服务器线程
        """
        if Network._server_running and Network._server_thread and Network._server_thread.is_alive():
            logging.info("服务器已经在运行中")
            return Network._server_thread
            
        Network._server_running = True
        Network._listening = True
        Network._server_thread = threading.Thread(
            target=Network._server_process,
            args=(port, callback)
        )
        Network._server_thread.daemon = True
        Network._server_thread.start()
        return Network._server_thread
    
    @staticmethod
    def _server_process(port, callback):
        """
        服务器处理函数，在单独的线程中运行。
        
        参数:
            port: 监听的端口
            callback: 当接收到命令时执行的可选回调函数
        """
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        
        try:
            server.bind(('0.0.0.0', port))
            server.listen(5)
            logging.info("服务器已在端口 {0} 上启动".format(port))
            
            # 设置超时，以便能够定期检查服务器是否应该继续运行
            server.settimeout(1.0)
            
            while Network._server_running:
                try:
                    client_socket, address = server.accept()
                    logging.info("来自 {0} 的连接".format(address))
                    client_handler = threading.Thread(
                        target=Network._handle_client,
                        args=(client_socket, address, callback)
                    )
                    client_handler.daemon = True
                    client_handler.start()
                except socket.timeout:
                    # 超时，继续循环
                    continue
                except Exception as e:
                    if Network._server_running:  # 只有当服务器应该在运行时才记录错误
                        logging.error("接受连接时出错: {0}".format(e))
                
        except Exception as e:
            if Network._server_running:  # 只有当服务器应该在运行时才记录错误
                logging.error("服务器错误: {0}".format(e))
        finally:
            try:
                server.close()
            except:
                pass
            Network._server_running = False
            logging.info("服务器已关闭")
    
    @staticmethod
    def stop_server():
        """
        停止正在运行的服务器。
        """
        Network._server_running = False
        if Network._server_thread and Network._server_thread.is_alive():
            Network._server_thread.join(timeout=5.0)
            if Network._server_thread.is_alive():
                logging.warning("服务器线程未能在5秒内关闭")
        Network._server_thread = None
        logging.info("服务器已停止")
    
    @staticmethod
    def pause_listening():
        """
        暂停监听消息（不处理新接收的消息）。
        """
        Network._listening = False
        logging.info("已暂停监听消息")
    
    @staticmethod
    def resume_listening():
        """
        恢复监听消息。
        """
        Network._listening = True
        logging.info("已恢复监听消息")
        
    @staticmethod
    def is_listening():
        """
        检查当前是否正在监听消息。
        
        返回:
            当前是否正在监听
        """
        return Network._listening
    
    @staticmethod
    def is_server_running():
        """
        检查服务器是否正在运行。
        
        返回:
            服务器是否正在运行
        """
        return Network._server_running
    
    @staticmethod
    def get_message():
        """
        从消息队列获取一条消息。如果队列为空，返回None。
        
        返回:
            消息字典或None
        """
        try:
            return Network._message_queue.get_nowait()
        except queue.Empty:
            return None
    
    @staticmethod
    def _handle_client(client_socket, address, callback):
        """
        处理客户端连接并处理接收到的命令。
        
        参数:
            client_socket: 客户端套接字
            address: 客户端地址元组 (ip, port)
            callback: 当接收到命令时执行的可选回调函数
        """
        try:
            # 首先接收数据大小
            size_data = client_socket.recv(8)
            if not size_data:
                return
                
            data_size = int(size_data.decode(Network.ENCODING).strip())
            
            # 接收实际数据
            received_data = b""
            while len(received_data) < data_size:
                chunk = client_socket.recv(min(data_size - len(received_data), Network.BUFFER_SIZE))
                if not chunk:
                    break
                received_data += chunk
            
            # 反序列化数据
            data = pickle.loads(received_data)
            
            # 获取消息类型
            cmd_type = data.get('type')
            
            # 如果是消息类型且处于暂停状态，则不处理
            if cmd_type == 'message' and not Network._listening:
                # 对于暂停状态下的消息，我们不记录也不处理
                response = {
                    'status': 'paused',
                    'message': "系统当前处于暂停状态，消息已接收但不会被处理"
                }
            else:
                # 处理命令
                response = Network._process_command(data, address[0])
            
            # 如果是消息类型且当前正在监听，则添加到消息队列
            if cmd_type == 'message' and Network._listening:
                # 将消息和发送者信息存储到队列中
                message_data = {
                    'sender': address[0],
                    'message': data.get('message', ''),
                    'timestamp': time.time(),
                    'raw_data': data
                }
                Network._message_queue.put(message_data)
            
            # 如果有回调函数且当前正在监听，调用回调函数
            if callback and Network._listening:
                callback(data, response, address)
        
            # 发送响应
            response_bytes = pickle.dumps(response)
            size_header = "{0:<8}".format(len(response_bytes)).encode(Network.ENCODING)
            client_socket.send(size_header)
            client_socket.sendall(response_bytes)
            
        except Exception as e:
            logging.error("处理客户端 {0} 时出错: {1}".format(address, e))
        finally:
            client_socket.close()
    
    @staticmethod
    def _process_command(data, sender_ip):
        """
        处理接收到的命令。
        
        参数:
            data: 命令数据字典
            sender_ip: 发送者的IP地址
            
        返回:
            包含响应的字典
        """
        cmd_type = data.get('type')
        response = {'status': 'error', 'message': '未知命令类型'}
        
        try:
            if cmd_type == 'execute':
                # 执行命令
                command = data.get('command')
                logging.info("执行命令: {0}".format(command))
                
                # 确定系统类型
                is_windows = platform.system().lower() == 'windows'
                
                # 根据系统类型选择编码
                system_encoding = 'gbk' if is_windows else 'utf-8'
                
                # 分析命令是单行还是多行
                command_lines = command.strip().split('\n')
                # 过滤掉注释行和空行
                valid_lines = [line for line in command_lines if line.strip() and not (line.strip().startswith('#') or line.strip().startswith('rem') or line.strip().startswith('@rem'))]
                
                # 如果只有一行有效命令，直接执行
                if len(valid_lines) <= 1:
                    logging.info("执行单行命令")
                    # 根据系统类型确定shell
                    shell = True
                    
                    # 执行命令
                    try:
                        process = subprocess.Popen(
                            command,
                            shell=shell,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            universal_newlines=False  # 改为False，我们将手动处理编码
                        )
                        
                        # 使用io.TextIOWrapper处理编码
                        stdout_wrapper = io.TextIOWrapper(process.stdout, encoding=system_encoding, errors='replace')
                        stderr_wrapper = io.TextIOWrapper(process.stderr, encoding=system_encoding, errors='replace')
                        
                        timeout = data.get('timeout', 60)
                        # 由于使用了TextIOWrapper，不能直接使用communicate
                        # 我们需要自己读取输出
                        stdout_data = ""
                        stderr_data = ""
                        
                        # 设置超时时间
                        end_time = time.time() + timeout
                        
                        # 非阻塞读取
                        while process.poll() is None:
                            # 检查是否超时
                            if time.time() > end_time:
                                process.kill()
                                raise subprocess.TimeoutExpired(command, timeout)
                            
                            # 读取标准输出
                            line = stdout_wrapper.readline()
                            if line:
                                stdout_data += line
                            
                            # 读取标准错误
                            line = stderr_wrapper.readline()
                            if line:
                                stderr_data += line
                            
                            # 避免CPU占用过高
                            time.sleep(0.01)
                        
                        # 读取剩余输出
                        for line in stdout_wrapper:
                            stdout_data += line
                        for line in stderr_wrapper:
                            stderr_data += line
                        
                        returncode = process.returncode
                        
                        # 添加返回值字段
                        # 如果stdout有内容则使用stdout的最后一行作为返回值，否则使用returncode
                        if stdout_data.strip():
                            # 拆分为行并获取最后一行
                            stdout_lines = stdout_data.strip().split('\n')
                            return_value = stdout_lines[-1].strip()
                        else:
                            return_value = str(returncode)
                        
                        response = {
                            'status': 'success' if returncode == 0 else 'error',
                            'returncode': returncode,
                            'stdout': stdout_data,
                            'stderr': stderr_data,
                            'return_value': return_value  # 新增返回值字段
                        }
                    except subprocess.TimeoutExpired:
                        process.kill()
                        # 使用与上面相同的方式读取已有输出
                        stdout_data = ""
                        stderr_data = ""
                        try:
                            # 读取剩余输出
                            for line in stdout_wrapper:
                                stdout_data += line
                            for line in stderr_wrapper:
                                stderr_data += line
                        except:
                            pass
                        
                        response = {
                            'status': 'error',
                            'message': "命令执行超时",
                            'returncode': -1,
                            'stdout': stdout_data,
                            'stderr': stderr_data,
                            'return_value': "timeout"  # 超时情况下设置特殊返回值
                        }
                    except Exception as e:
                        response = {
                            'status': 'error',
                            'message': str(e),
                            'returncode': -1,
                            'stdout': '',
                            'stderr': str(e),
                            'return_value': "exception: " + str(e)  # 异常情况下设置特殊返回值
                        }
                else:
                    logging.info("执行多行命令，使用临时文件")
                    # 创建临时文件来存储命令
                    # 确定系统类型并设置适当的文件扩展名和执行命令
                    file_ext = '.bat' if is_windows else '.sh'
                    
                    # 创建唯一的临时文件名
                    temp_dir = tempfile.gettempdir()
                    temp_file_name = "cmd_" + str(uuid.uuid4()) + file_ext
                    temp_file_path = os.path.join(temp_dir, temp_file_name)
                    
                    try:
                        # 写入命令到临时文件，确保编码正确
                        with open(temp_file_path, 'w', encoding=system_encoding) as f:
                            f.write(command)
                        
                        # 设置文件权限（仅在非Windows系统上）
                        if not is_windows:
                            os.chmod(temp_file_path, 0o755)
                        
                        # 根据系统类型构建执行命令
                        if is_windows:
                            exec_command = ['cmd', '/c', temp_file_path]
                        else:
                            exec_command = ['/bin/bash', temp_file_path]
                        
                        # 执行命令
                        timeout = data.get('timeout', 60)
                        process = subprocess.Popen(
                            exec_command,
                            shell=False,  # 不使用shell，因为我们直接执行解释器
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            universal_newlines=False  # 改为False，我们将手动处理编码
                        )
                        
                        # 使用io.TextIOWrapper处理编码
                        stdout_wrapper = io.TextIOWrapper(process.stdout, encoding=system_encoding, errors='replace')
                        stderr_wrapper = io.TextIOWrapper(process.stderr, encoding=system_encoding, errors='replace')
                        
                        # 设置超时时间
                        end_time = time.time() + timeout
                        
                        # 非阻塞读取
                        stdout_data = ""
                        stderr_data = ""
                        
                        while process.poll() is None:
                            # 检查是否超时
                            if time.time() > end_time:
                                process.kill()
                                raise subprocess.TimeoutExpired(exec_command, timeout)
                                
                            # 读取标准输出
                            line = stdout_wrapper.readline()
                            if line:
                                stdout_data += line
                            
                            # 读取标准错误
                            line = stderr_wrapper.readline()
                            if line:
                                stderr_data += line
                                
                            # 避免CPU占用过高
                            time.sleep(0.01)
                            
                        # 读取剩余输出
                        for line in stdout_wrapper:
                            stdout_data += line
                        for line in stderr_wrapper:
                            stderr_data += line
                            
                        returncode = process.returncode
                        
                        # 添加返回值字段
                        # 如果stdout有内容则使用stdout的最后一行作为返回值，否则使用returncode
                        if stdout_data.strip():
                            # 拆分为行并获取最后一行
                            stdout_lines = stdout_data.strip().split('\n')
                            return_value = stdout_lines[-1].strip()
                        else:
                            return_value = str(returncode)
                        
                        response = {
                            'status': 'success' if returncode == 0 else 'error',
                            'returncode': returncode,
                            'stdout': stdout_data,
                            'stderr': stderr_data,
                            'return_value': return_value  # 新增返回值字段
                        }
                        
                    except subprocess.TimeoutExpired:
                        # 超时处理
                        try:
                            process.kill()
                        except:
                            pass
                            
                        # 读取已有输出
                        stdout_data = ""
                        stderr_data = ""
                        try:
                            for line in stdout_wrapper:
                                stdout_data += line
                            for line in stderr_wrapper:
                                stderr_data += line
                        except:
                            pass
                            
                        response = {
                            'status': 'error',
                            'message': "命令执行超时",
                            'returncode': -1,
                            'stdout': stdout_data,
                            'stderr': stderr_data,
                            'return_value': "timeout"  # 超时情况下设置特殊返回值
                        }
                    except Exception as e:
                        # 处理其他异常
                        try:
                            process.kill()
                        except:
                            pass
                        
                        stdout_data = ""
                        stderr_data = str(e)
                        
                        response = {
                            'status': 'error',
                            'message': str(e),
                            'returncode': -1,
                            'stdout': stdout_data,
                            'stderr': stderr_data,
                            'return_value': "exception: " + str(e)  # 异常情况下设置特殊返回值
                        }
                    finally:
                        # 清理临时文件
                        try:
                            if os.path.exists(temp_file_path):
                                os.remove(temp_file_path)
                        except Exception as e:
                            logging.error("清理临时文件失败: {0}".format(e))
            
            elif cmd_type == 'file_transfer':
                # 处理文件传输
                file_path = data.get('file_path')
                file_data = data.get('file_data')
                
                if file_path and file_data:
                    # 确保文件路径是绝对路径
                    file_path = os.path.abspath(file_path) if not os.path.isabs(file_path) else file_path
                    
                    # 确保目标目录存在
                    dir_path = os.path.dirname(file_path)
                    if not os.path.exists(dir_path):
                        os.makedirs(dir_path)
                    
                    # 写入文件
                    with open(file_path, 'wb') as f:
                        f.write(file_data)
                    
                    response = {
                        'status': 'success',
                        'message': "文件已保存到 {0}".format(file_path)
                    }
                else:
                    response = {
                        'status': 'error',
                        'message': '缺少文件路径或文件数据'
                    }
            
            elif cmd_type == 'message':
                # 处理消息
                message = data.get('message')
                
                # 只有在监听状态才记录和处理消息
                if Network._listening:
                    logging.info("接收到消息: {0}".format(message))
                    response = {
                        'status': 'success',
                        'message': "消息已接收: {0}".format(message)
                    }
                else:
                    # 处于暂停状态，返回特殊状态
                    response = {
                        'status': 'paused',
                        'message': "系统当前处于暂停状态，消息已接收但不会被处理"
                    }
                    
            elif cmd_type == 'ping':
                # 简单的ping命令
                response = {
                    'status': 'success',
                    'message': 'pong',
                    'system_info': {
                        'platform': platform.platform(),
                        'system': platform.system(),
                        'node': platform.node(),
                        'release': platform.release(),
                        'version': platform.version(),
                        'processor': platform.processor()
                    }
                }
                
        except Exception as e:
            response = {
                'status': 'error',
                'message': str(e)
            }
            
        return response
    
    @staticmethod
    def send_message(target_ip, message, port=DEFAULT_PORT, timeout=TIMEOUT):
        """
        发送消息到目标机器。
        
        参数:
            target_ip: 目标机器的IP地址
            message: 要发送的消息
            port: 要连接的端口
            timeout: 超时时间（秒）
            
        返回:
            包含来自目标的响应的字典
        """
        data = {
            'type': 'message',
            'message': message,
            'timeout': timeout
        }
        
        return Network._send_data(target_ip, port, data)
    
    @staticmethod
    def send_command(target_ip, command, port=DEFAULT_PORT, timeout=60):
        """
        发送要在目标机器上执行的命令。
        
        参数:
            target_ip: 目标机器的IP地址
            command: 要执行的命令
            port: 要连接的端口
            timeout: 命令执行超时时间（秒）
            
        返回:
            包含来自目标的响应的字典
        """
        data = {
            'type': 'execute',
            'command': command,
            'timeout': timeout
        }
        
        return Network._send_data(target_ip, port, data)
    
    @staticmethod
    def send_file(target_ip, local_path, remote_path, port=DEFAULT_PORT):
        """
        向目标机器发送文件。
        
        参数:
            target_ip: 目标机器的IP地址
            local_path: 本地文件路径（支持相对和绝对路径）
            remote_path: 文件应保存在远程机器上的路径（支持相对和绝对路径）
            port: 要连接的端口
            
        返回:
            包含来自目标的响应的字典
        """
        try:
            # 处理本地路径，支持相对和绝对路径
            local_path = os.path.abspath(local_path) if not os.path.isabs(local_path) else local_path
            
            # 检查本地文件是否存在
            if not os.path.exists(local_path):
                return {'status': 'error', 'message': "本地文件不存在: {0}".format(local_path)}
            
            # 检查本地文件是否为文件（非目录）
            if not os.path.isfile(local_path):
                return {'status': 'error', 'message': "指定路径不是一个文件: {0}".format(local_path)}
                
            with open(local_path, 'rb') as f:
                file_data = f.read()
                
            data = {
                'type': 'file_transfer',
                'file_path': remote_path,
                'file_data': file_data
            }
            
            return Network._send_data(target_ip, port, data)
            
        except Exception as e:
            return {'status': 'error', 'message': "文件传输错误: {0}".format(str(e))}
    
    @staticmethod
    def ping(target_ip, port=DEFAULT_PORT):
        """
        ping目标机器以检查它是否在线并获取系统信息。
        
        参数:
            target_ip: 目标机器的IP地址
            port: 要连接的端口
            
        返回:
            包含来自目标的响应的字典
        """
        data = {'type': 'ping'}
        return Network._send_data(target_ip, port, data)
    
    @staticmethod
    def _send_data(target_ip, port, data):
        """
        向目标机器发送数据并接收响应。
        
        参数:
            target_ip: 目标机器的IP地址
            port: 要连接的端口
            data: 要发送的数据字典
            
        返回:
            包含来自目标的响应的字典
        """
        # 设置最大重试次数和重试间隔
        max_retries = 3
        retry_interval = 5
        
        for retry_count in range(max_retries + 1):  # +1是因为第一次不算重试
            client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client.settimeout(data.get('timeout', Network.TIMEOUT))
            
            try:
                client.connect((target_ip, port))
                
                # 序列化数据
                serialized_data = pickle.dumps(data)
                
                # 首先发送数据大小
                size_header = "{0:<8}".format(len(serialized_data)).encode(Network.ENCODING)
                client.send(size_header)
                
                # 发送实际数据
                client.sendall(serialized_data)
                
                # 接收响应大小
                size_data = client.recv(8)
                if not size_data:
                    raise Exception('服务器没有响应')
                    
                data_size = int(size_data.decode(Network.ENCODING).strip())
                
                # 接收实际响应
                received_data = b""
                while len(received_data) < data_size:
                    chunk = client.recv(min(data_size - len(received_data), Network.BUFFER_SIZE))
                    if not chunk:
                        break
                    received_data += chunk
                
                # 反序列化响应
                response = pickle.loads(received_data)
                return response
                
            except socket.timeout:
                # 超时错误不进行重试
                logging.error("连接到 {0}:{1} 超时".format(target_ip, port))
                return {'status': 'error', 'message': "连接到 {0}:{1} 超时".format(target_ip, port)}
            except socket.error as e:
                # 非超时的socket错误，进行重试
                if retry_count < max_retries:
                    logging.warning("连接到 {0}:{1} 失败: {2}，{3}秒后将进行第{4}次重试".format(
                        target_ip, port, str(e), retry_interval, retry_count + 1))
                    time.sleep(retry_interval)
                    continue
                else:
                    logging.error("连接到 {0}:{1} 失败: {2}，已达到最大重试次数".format(target_ip, port, str(e)))
                    return {'status': 'error', 'message': "连接到 {0}:{1} 失败: {2}，重试{3}次后依然失败".format(
                        target_ip, port, str(e), max_retries)}
            except Exception as e:
                # 其他异常，进行重试
                if retry_count < max_retries:
                    logging.warning("发送数据时出错: {0}，{1}秒后将进行第{2}次重试".format(
                        str(e), retry_interval, retry_count + 1))
                    time.sleep(retry_interval)
                    continue
                else:
                    logging.error("发送数据时出错: {0}，已达到最大重试次数".format(str(e)))
                    return {'status': 'error', 'message': str(e)}
            finally:
                client.close()
        
        # 这里不应该到达，但为了代码完整性添加
        return {'status': 'error', 'message': '未知错误，所有重试均失败'}
    
    @staticmethod
    def send_message_async(target_ip, message, port=DEFAULT_PORT, timeout=TIMEOUT, callback=None):
        """
        异步发送消息到目标机器。
        
        参数:
            target_ip: 目标机器的IP地址
            message: 要发送的消息
            port: 要连接的端口
            timeout: 超时时间（秒）
            callback: 操作完成后调用的回调函数，接收结果字典作为参数
            
        返回:
            Future对象，可用于获取结果
        """
        def _send_and_callback(ip, msg, p, t):
            result = Network.send_message(ip, msg, port=p, timeout=t)
            if callback:
                callback(result)
            return result
        
        return Network._thread_pool.submit(_send_and_callback, target_ip, message, port, timeout)
    
    @staticmethod
    def send_command_async(target_ip, command, port=DEFAULT_PORT, timeout=60, callback=None):
        """
        异步发送要在目标机器上执行的命令。
        
        参数:
            target_ip: 目标机器的IP地址
            command: 要执行的命令
            port: 要连接的端口
            timeout: 命令执行超时时间（秒）
            callback: 操作完成后调用的回调函数，接收结果字典作为参数
            
        返回:
            Future对象，可用于获取结果
        """
        def _send_and_callback(ip, cmd, p, t):
            result = Network.send_command(ip, cmd, port=p, timeout=t)
            if callback:
                callback(result)
            return result
            
        return Network._thread_pool.submit(_send_and_callback, target_ip, command, port, timeout)
    
    @staticmethod
    def send_file_async(target_ip, local_path, remote_path, port=DEFAULT_PORT, callback=None):
        """
        异步向目标机器发送文件。
        
        参数:
            target_ip: 目标机器的IP地址
            local_path: 本地文件路径（支持相对和绝对路径）
            remote_path: 文件应保存在远程机器上的路径（支持相对和绝对路径）
            port: 要连接的端口
            callback: 操作完成后调用的回调函数，接收结果字典作为参数
            
        返回:
            Future对象，可用于获取结果
        """
        def _send_and_callback(ip, local, remote, p):
            result = Network.send_file(ip, local, remote, port=p)
            if callback:
                callback(result)
            return result
            
        return Network._thread_pool.submit(_send_and_callback, target_ip, local_path, remote_path, port)
    
    @staticmethod
    def ping_async(target_ip, port=DEFAULT_PORT, callback=None):
        """
        异步ping目标机器以检查它是否在线并获取系统信息。
        
        参数:
            target_ip: 目标机器的IP地址
            port: 要连接的端口
            callback: 操作完成后调用的回调函数，接收结果字典作为参数
            
        返回:
            Future对象，可用于获取结果
        """
        def _send_and_callback(ip, p):
            result = Network.ping(ip, port=p)
            if callback:
                callback(result)
            return result
            
        return Network._thread_pool.submit(_send_and_callback, target_ip, port)
    
    @staticmethod
    def shutdown():
        """
        关闭网络相关的所有资源，包括服务器和线程池。
        在应用程序退出前调用。
        """
        # 停止服务器
        Network.stop_server()
        
        # 关闭线程池
        Network._thread_pool.shutdown(wait=True)
        
        logging.info("网络资源已关闭") 